/****************LED灯有关实现函数********************
 * 作者：宁晓兰
 ******************************************************************/

#include "led.h"

/***************************数码管段选***************************/
u8 segTable[] = {
	0x3f, // 1
	0x06,
	0x5b,
	0x4f,
	0x66, // 5
	0x6d,
	0x7d,
	0x07,
	0x7f,
	0x6f,
	0x00,
	0x77, /*A 11*/
	0x7C, /*b*/
	0x39, /*C*/
	0x58, /*c*/
	0x5E, /*d 15*/
	0x79, /*E*/
	0x71, /*F*/
	0x76, /*H*/
	0x74, /*h*/
	0x38, /*L  20*/
	0x54, /*n*/
	0x37, /*N*/
	0x5C, /*o*/
	0x73, /*P*/
	0x50, /*r  25*/
	0x78, /*t*/
	0x3E, /*U*/
	0x40 /*-*/};
u8 segTablePortation[] = {0xbf, 0x86, 0xdb, 0xcf, 0xe6, 0xed, 0xfd, 0x87, 0xff, 0xef, 0x00}; // 带小数点
/****************************************************
 * 初始化二极管LED灯的引脚端口
 ******************************************************/
void LED_Init()
{
	RCC->APB2ENR |= 1 << 0; // 使能AFIO
	RCC->APB2ENR |= 1 << 3; // 使能PORTB时钟
	RCC->APB2ENR |= 1 << 6; // 使能PORTE时钟

	AFIO->MAPR |= 0x02000000; // 复用口设置	设置PB.3为I/O口可用，且可以SW仿真

	GPIOB->CRL &= 0xFFFF0000;
	GPIOB->CRL |= 0x00003333; // PB.3推挽输出
	GPIOB->ODR |= 0x000000FF; // PB.3输出高

	GPIOE->CRH &= 0X00000000;
	GPIOE->CRH |= 0X33333333; // PE.8-15推挽输出
	GPIOE->ODR |= 0x0000FF00; // PE.8-15输出高
}

/***************************************
 * 流水灯选择，或数码管段选
 * value:显示的数值对应的段选二进制值
 ****************************************/
void LedValue(u8 value)
{
	GPIOE->ODR &= ~(0xff << 8);
	GPIOE->ODR |= value << 8;
	// LED0 = (value & 0x01) ? 1 : 0;
	// LED1 = (value & 0x02) ? 1 : 0;
	// LED2 = (value & 0x03) ? 1 : 0;
	// LED3 = (value & 0x04) ? 1 : 0;
	// LED4 = (value & 0x05) ? 1 : 0;
	// LED5 = (value & 0x06) ? 1 : 0;
	// LED6 = (value & 0x07) ? 1 : 0;
	// LED7 = (value & 0x08) ? 1 : 0;
}
void SetLedValue(u8 value, int SwitchLed)
{
	switch (value)
	{
	case 1:
		LED0 = SwitchLed;
		break;
	case 2:
		LED1 = SwitchLed;
		break;
	case 3:
		LED2 = SwitchLed;
		break;
	case 4:
		LED3 = SwitchLed;
		break;
	case 5:
		LED4 = SwitchLed;
		break;
	case 6:
		LED5 = SwitchLed;
		break;
	case 7:
		LED6 = SwitchLed;
		break;
	case 8:
		LED7 = SwitchLed;
		break;
	default:
		break;
	}
}

/***************************************
 * 数码管显示不带小数点的数值
 * 参数 w:显示的位置，即位选，左-右：0-7
 *      value:要显示的数值
 ****************************************/
void SetLed(u8 w, u8 value)
{
	SEL0 = w % 2;
	SEL1 = w / 2 % 2;
	SEL2 = w / 4;
	LedValue(segTable[value]);
}

/***************************************
 * 数码管显示带小数点的数值
 * 参数 w:显示的位置，即位选，左-右：0-7
 *      value:要显示的数值
 ****************************************/
void PortationDisplay(u8 w, u8 value)
{
	SEL0 = w % 2;
	SEL1 = w / 2 % 2;
	SEL2 = w / 4;
	LedValue(segTablePortation[value]);
}
